/**
 * 
 */
package cz.cuni.mff.abacs.burglar.logics;

import java.util.List;

import aStarLibrary.Node;
import cz.cuni.mff.abacs.burglar.logics.objects.BaseObject;
import cz.cuni.mff.abacs.burglar.logics.objects.Room;
import cz.cuni.mff.abacs.burglar.logics.objects.agents.Agent;
import cz.cuni.mff.abacs.burglar.logics.objects.agents.Burglar;
import cz.cuni.mff.abacs.burglar.logics.objects.agents.Guard;
import cz.cuni.mff.abacs.burglar.logics.objects.items.Item;
import cz.cuni.mff.abacs.burglar.logics.objects.positions.Position;
import cz.cuni.mff.abacs.burglar.logics.planning.instructions.Instruction;


/**
 * 
 * 
 * @author abacs
 *
 */
public interface GameMap {
	
	
	/**  */
	public static enum StepResult {
		FINISHED,
		IMPORTANT_CHANGE,
		NOTHING
	}
	
	
	// getters:
	
	/**
	 * 
	 * @param id
	 * @return
	 */
	public Position getPosition(int id);
	
	
	/**
	 * 
	 * @param id
	 * @return
	 */
	public Position getPosition(Node node);
	
	
	/**
	 * Returns the position on the selected coordinates.
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	public Position getPosition(int x, int y);
	
	
	/**
	 * 
	 * @return
	 */
	public List<Position> getPositions();
	
	
	/**
	 * 
	 * @return
	 */
	public List<Position> getOperablePositions();
	
	
	/**
	 * Only returns the rooms with trap positions, no guard patroled rooms are included.
	 * 
	 * @return
	 */
	public List<Room> getTrapRooms();
	
	
	/**
	 * Only returns the rooms with trap positions, no guard patroled rooms are included.
	 * 
	 * @return
	 */
	public List<Integer> getTrapRoomIds();
	
	
	/**
	 * 
	 * @return
	 */
	public List<Room> getRooms();
	
	
	/**
	 * 
	 * @return
	 */
	public List<Integer> getRoomIds();
	
	
	/**
	 * 
	 * @param id
	 * @return
	 */
	public Room getRoom(int id);
	
	
	/**
	 * 
	 * 
	 * @return
	 */
	public List<Item> getItems();
	
	
	/**
	 * 
	 * 
	 * @param id
	 * @return
	 */
	public Item getItem(int id);
	
	
	/**
	 * 
	 * @return
	 */
	public List<Agent> getAgents();
	
	
	/**
	 * 
	 * 
	 * @param id
	 * @return
	 */
	public Agent getAgent(int id);
	
	
	/**
	 * 
	 * 
	 * @return
	 */
	public Burglar getBurglar();
	
	
	/**
	 * 
	 * 
	 * @return
	 */
	public List<Guard> getGuards();
	
	
	// -------------------------------------------------------------------------
	
	
	/**
	 * Returns the objects on the selected coordinates.
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	public List<BaseObject> getObjectsOnPosition(int x, int y);
	
	
	// -------------------------------------------------------------------------
	
	
	/** 
	 * Returns the number of horizontal game map positions.
	 * 
	 * @return
	 */
	public int getWidth();
	
	
	/** 
	 * Returns the number of vertical game map positions.
	 * 
	 * @return
	 */
	public int getHeight();
	
	
	// -------------------------------------------------------------------------
	
	
	/**
	 * 
	 * @return
	 */
	public int getRequiredTrapRoomCount();
	
	
	// -------------------------------------------------------------------------
	
	
	/** 
	 * Executes a single step for each agent.
	 * 
	 * @return 
	 * */
	public StepResult executeStep();
	
	
	/**
	 *  Adds the list of instructions to the map.
	 *  
	 *  @param instructions
	 *   */
	public void addInstructions(List<Instruction> instructions);
	
	
	
	public void clearInstructions();
	
	
	/**
	 * Returns the instruction list for a selected agent. 
	 * 
	 * @param agentId
	 * @return
	 */
	public List<Instruction> getAgentInstructions(int agentId);
	
	
	/**
	 * Returns the instruction list for a selected agent.
	 *  
	 * @param agent
	 * @return
	 */
	public List<Instruction> getAgentInstructions(Agent agent);
	
	
	/**
	 * Compares two instructionlists.
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public boolean instructionListsMatch(List<Instruction> a, List<Instruction> b);
	
	
	/**
	 * 
	 * @param list
	 * @return rooms where the instructions will trigger a trap.
	 */
	public List<Room> instructionsLeadToTraps(List<Instruction> list);
	
	
	// -------------------------------------------------------------------------
	
	
	/**
	 * 
	 * @param nodes
	 * @return 
	 */
	public List<Position> nodesToPositions(List<Node> nodes);
	
	
	// -------------------------------------------------------------------------
	
	
	/**
	 * 
	 * @return
	 */
	public boolean isBurglarTrapped();
	
	
}
